import 'dart:async';
import 'dart:io';

import 'package:PollOnLine/utils/utils.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:wakelock_plus/wakelock_plus.dart';

import '../../utils/logger_utils.dart';
import '../../utils/path_provider_utils.dart';
import '../../utils/prevent_tap_utils.dart';
import '../../values/MyColors.dart';
import '../IconText.dart';
import 'camera_utils.dart';
import 'media.dart';

class CameraPage extends StatefulWidget {
  final String? dirName;

  // 视频时长 多少秒 默认300
  final int maxRecordDuration;

  const CameraPage({
    Key? key,
    this.dirName,
    this.maxRecordDuration = 300,
  }) : super(key: key);

  @override
  State<CameraPage> createState() => _CameraPageState();
}

class _CameraPageState extends State<CameraPage> with WidgetsBindingObserver {
  CameraController? controller;

  // 相机是否已初始化
  bool _isCameraInitialized = false;

  ///翻转相机
  bool _isRearCameraSelected = true;

  ///图像视频切换
  bool _isVideoCameraSelected = false;

  ///视频录制
  bool _isRecordingInProgress = false;

  File? _imageFile;
  File? _videoFile;

  Timer? _timer;

  int _startRecordDuration = 0; // 视频开始时间
  String? _recordTimeStr; // 视频开始录制时间 格式

  FlashMode? _currentFlashMode; // 闪光灯

  List<CameraDescription> cameras = []; // 获取设备的 相机

  List<String> rowTitle = ['照片', '视频'];

  // 1、初始化一个新的相机控制器，这是启动相机屏幕所需要的
  // 2、当用户翻转相机视图或改变相机清晰度时，处置之前的控制器并用具有不同属性的新控制器替换它
  void onNewCameraSelected(CameraDescription cameraDescription) async {
    final previousCameraController = controller;
    // Instantiating the camera controller 实例化摄像机控制器
    final CameraController cameraController = CameraController(
      cameraDescription,
      ResolutionPreset.high,
      imageFormatGroup: ImageFormatGroup.jpeg,
    );

    // Dispose the previous controller 清除前一个控制器
    await previousCameraController?.dispose();

    // Replace with the new controller 更换控制器
    if (mounted) {
      setState(() {
        controller = cameraController;
      });
    }
    // The flash mode the camera is currently set to. 相机当前设置的闪光模式。
    _currentFlashMode = cameraController.value.flashMode;

    // Update UI if controller updated 更新控制器后更新UI
    cameraController.addListener(() {
      if (mounted) setState(() {});
    });

    // Initialize controller 初始化控制器
    try {
      await cameraController.initialize();
    } on CameraException catch (e) {
      print('Error initializing camera: $e');
    }

    // Update the boolean
    if (mounted) {
      setState(() {
        _isCameraInitialized = controller!.value.isInitialized;
      });
    }
  }

  /// 生命周期变化时回调
  /// 是监听点击home、或者物理返回键，将app的页面从后台切换到前台进程才会触发。
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    kLog.v("camera lifeChanged： $state");

    final CameraController? cameraController = controller;
    // App state changed before we got the chance to initialize.
    if (cameraController == null || !cameraController.value.isInitialized) {
      return;
    }
    //  resumed:应用可见并可响应用户操作
    //  inactive:用户可见，但不可响应用户操作
    //  paused:已经暂停了，用户不可见、不可操作
    //  suspending：应用被挂起，此状态IOS永远不会回调
    if (state == AppLifecycleState.inactive) {
      // cameraController.dispose();
    } else if (state == AppLifecycleState.resumed) {
      if (Platform.isAndroid) {
        // if (_isVideoCameraSelected) {
        //   if (_isRecordingInProgress) {
        //     _endTakeVideo();
        //   }
        // } else {
        //   onNewCameraSelected(cameraController.description);
        // }
      } else {
        onNewCameraSelected(cameraController.description);
      }
    } else if (state == AppLifecycleState.paused) {
      // Get.back( );
      // if (_isVideoCameraSelected) {
      //   if (_isRecordingInProgress) {
      //     _endTakeVideo();
      //   }
      // }
    }
  }

  @override
  void initState() {
    //添加观察者
    WidgetsBinding.instance.addObserver(this);
    // SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
    // SystemChrome.setEnabledSystemUIMode(mode)
    cameras = CameraUtils().cameras;

    // 索引0的cameras名单-后置摄像头
    // 索引1的cameras名单-前置摄像头
    onNewCameraSelected(cameras[0]);
    // 设置屏幕长亮
    WakelockPlus.enable();
    super.initState();
  }

  @override
  void dispose() {
    controller?.dispose();
    WidgetsBinding.instance.removeObserver(this); //销毁观察者
    // videoController?.dispose();

    _timer?.cancel();
    _timer = null;
    // 销毁屏幕长亮

    WakelockPlus.disable();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        return Future.value(true);
      },
      child: OrientationBuilder(builder: (context, orientation) {
        return Scaffold(
          backgroundColor: Colors.black,
          body: _isCameraInitialized
              ? GestureDetector(
                  onHorizontalDragEnd: (DragEndDetails details) {
                    // 视频拍摄中，禁止左右滑动
                    if (!_isRecordingInProgress) {
                      // 点击屏幕无效
                      if (details.velocity.pixelsPerSecond.dx == 0) {
                        return;
                      }
                      if (details.velocity.pixelsPerSecond.dx < 80) {
                        ///左滑
                        if (!_isVideoCameraSelected) {
                          setState(() {
                            _isVideoCameraSelected = true;
                          });
                        }
                      } else {
                        ///右滑
                        if (_isVideoCameraSelected) {
                          setState(() {
                            _isVideoCameraSelected = false;
                          });
                        }
                      }
                    }
                  },
                  child: Stack(
                    children: [
                      SizedBox(
                        width: Get.width,
                        child: Align(
                          alignment: Alignment.topCenter,
                          child: AspectRatio(
                            aspectRatio: orientation == Orientation.portrait ? 1 / controller!.value.aspectRatio : controller!.value.aspectRatio,
                            child: CameraPreview(controller!),
                          ),
                        ),
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          Container(
                            height: isPad(context) ? Get.height * 0.2 : Get.height - controller!.value.aspectRatio * Get.width,
                            decoration: const BoxDecoration(color: Colors.black),
                            alignment: Alignment.center,
                            child: SafeArea(
                              top: false,
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                children: [
                                  Row(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: rowTitle
                                        .asMap()
                                        .map((key, value) => MapEntry(
                                            key,
                                            GestureDetector(
                                              onTap: () {
                                                if (!_isRecordingInProgress) {
                                                  if (key == 1) {
                                                    ///左滑
                                                    if (!_isVideoCameraSelected) {
                                                      setState(() {
                                                        _isVideoCameraSelected = true;
                                                      });
                                                    }
                                                  } else {
                                                    ///右滑
                                                    if (_isVideoCameraSelected) {
                                                      setState(() {
                                                        _isVideoCameraSelected = false;
                                                      });
                                                    }
                                                  }
                                                }
                                              },
                                              child: Container(
                                                padding: EdgeInsets.symmetric(horizontal: 10.r, vertical: 5.h),
                                                child: Text(
                                                  value,
                                                  style: TextStyle(
                                                    color: (key == (_isVideoCameraSelected ? 1 : 0)) ? Colors.orange : Colors.white,
                                                    fontSize: 15.r,
                                                  ),
                                                ),
                                              ),
                                            )))
                                        .values
                                        .toList(),
                                  ),
                                  Padding(
                                    padding: EdgeInsets.symmetric(horizontal: 20.r),
                                    child: Row(
                                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                      children: [
                                        InkWell(
                                          onTap: () async {
                                            setState(() {
                                              _currentFlashMode = _currentFlashMode == FlashMode.off ? FlashMode.torch : FlashMode.off;
                                            });
                                            await controller!.setFlashMode(
                                              _currentFlashMode!,
                                            );
                                          },
                                          child: _currentFlashMode != FlashMode.torch
                                              ? Icon(
                                                  Icons.flash_off,
                                                  color: Colors.white,
                                                  size: 30.r,
                                                )
                                              : Icon(
                                                  Icons.flash_on,
                                                  color: Colors.white,
                                                  size: 30.r,
                                                ),
                                        ),
                                        GestureDetector(
                                          onTap: () async {
                                            if (PreventTapUtils().multiTouch()) {
                                              return;
                                            }
                                            if (_isVideoCameraSelected) {
                                              if (_isRecordingInProgress) {
                                                _endTakeVideo();
                                              } else {
                                                _startTakeVideo();
                                              }
                                              return;
                                            }
                                            XFile? file = await takePicture();
                                            Get.back(result: MediaModel(isImage: true, file: file));
                                          },
                                          child: Stack(
                                            alignment: Alignment.center,
                                            children: [
                                              Icon(Icons.circle, color: Colors.white38, size: 80.r),
                                              Icon((_isVideoCameraSelected && _isRecordingInProgress) ? Icons.stop_rounded : Icons.circle,
                                                  color: _isVideoCameraSelected ? Colors.red : Colors.white,
                                                  size: (_isVideoCameraSelected && _isRecordingInProgress) ? 60.r : 65.r),
                                            ],
                                          ),
                                        ),
                                        InkWell(
                                          onTap: () {
                                            setState(() {
                                              _isCameraInitialized = false;
                                            });
                                            setState(() {
                                              _isRearCameraSelected = !_isRearCameraSelected;
                                            });
                                            onNewCameraSelected(
                                              cameras[_isRearCameraSelected ? 0 : 1],
                                            );
                                          },
                                          child: Visibility(
                                            maintainAnimation: true,
                                            maintainState: true,
                                            //隐藏需要占位，前俩个也需要为true，内部断言会判断,不需要时都为false,maintainState影响是否加载
                                            maintainSize: true,
                                            visible: !_isRecordingInProgress,
                                            child: Icon(
                                              _isRearCameraSelected ? Icons.flip_camera_ios_outlined : Icons.flip_camera_ios_outlined,
                                              color: Colors.white,
                                              size: 30.r,
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ],
                      ),
                      SafeArea(
                        child: Container(
                          margin: EdgeInsets.only(top: 10.r, left: 10.r),
                          child: IconButton(
                            padding: const EdgeInsets.all(0),
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                            icon: Icon(
                              Icons.arrow_back_ios_outlined,
                              color: Colors.white,
                              size: 20.r,
                            ),
                          ),
                        ),
                      ),
                      Visibility(
                        visible: _isVideoCameraSelected,
                        child: SafeArea(
                          child: Align(
                            alignment: Alignment.topCenter,
                            child: Column(
                              children: [
                                Container(
                                  width: 95.r,
                                  alignment: Alignment.center,
                                  padding: EdgeInsets.only(top: 2.r, bottom: 1.r),
                                  decoration: BoxDecoration(
                                    color: MyColors.FFEA4F3D,
                                    borderRadius: BorderRadius.circular(5),
                                  ),
                                  margin: EdgeInsets.only(top: 20.r),
                                  child: Text(
                                    _recordTimeStr ?? '00:00:00',
                                    style: TextStyle(color: Colors.white, fontSize: 20.r),
                                  ),
                                ),
                                Container(
                                  margin: EdgeInsets.only(top: 5.r),
                                  padding: EdgeInsets.only(top: 2.r, bottom: 3.r, left: 8.r, right: 8.r),
                                  decoration: BoxDecoration(
                                    color: MyColors.FF23201E,
                                    borderRadius: BorderRadius.circular(15.r),
                                  ),
                                  child: IconText(
                                    '最大拍摄时长 ${widget.maxRecordDuration ~/ 60} 分钟',
                                    icon: Icon(Icons.error_outline, size: 16.r),
                                    padding: EdgeInsets.only(right: 5.r),
                                    style: TextStyle(color: Colors.white, fontSize: 14.r),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                )
              : Container(),
        );
      }),
    );
  }

  /// 拍照
  Future<XFile?> takePicture() async {
    final CameraController? cameraController = controller;
    if (cameraController == null || !cameraController.value.isInitialized) {
      print('Error: select a camera first.');
      return null;
    }
    if (cameraController.value.isTakingPicture) {
      // A capture is already pending, do nothing.
      return null;
    }
    try {
      XFile file = await cameraController.takePicture();
      if (widget.dirName != null) {
        String dir = "${await PathProviderUtils().getTempDir()}/${widget.dirName}";
        String newPath = await PathProviderUtils().isExists(dir);

        int currentUnix = DateTime.now().millisecondsSinceEpoch;
        String fileFormat = file.path.split('.').last;

        newPath = '$newPath/$currentUnix.$fileFormat';

        File image = await File(file.path).copy(newPath);

        await PathProviderUtils().deleteFile(file.path);

        file = XFile(image.path);
      }
      return file;
    } on CameraException catch (e) {
      print('Error occured while taking picture: $e');
      return null;
    }
  }

  Future<void> _startTakeVideo() async {
    if (_isRecordingInProgress) {
      XFile? rawVideo = await stopVideoRecording();
      File videoFile = File(rawVideo!.path);

      int currentUnix = DateTime.now().millisecondsSinceEpoch;

      final directory = await PathProviderUtils().getCacheDir();
      String fileFormat = videoFile.path.split('.').last;

      _videoFile = await videoFile.copy(
        '${directory.path}/$currentUnix.$fileFormat',
      );
    } else {
      await startVideoRecording();
    }
  }

  Future<void> _endTakeVideo() async {
    if (!_isVideoCameraSelected) {
      return;
    }
    XFile? file = await stopVideoRecording();

    if (widget.dirName != null) {
      String dir = "${await PathProviderUtils().getTempDir()}/${widget.dirName}";
      String newPath = await PathProviderUtils().isExists(dir);

      int currentUnix = DateTime.now().millisecondsSinceEpoch;
      String fileFormat = file!.path.split('.').last;

      newPath = '$newPath/$currentUnix.$fileFormat';

      File image = await File(file.path).copy(newPath);

      await PathProviderUtils().deleteFile(file.path);

      file = XFile(image.path);
    }
    Get.back(result: MediaModel(isImage: false, file: file));
  }

  /// 开始视频录制过程
  Future<void> startVideoRecording() async {
    final CameraController? cameraController = controller;
    if (controller!.value.isRecordingVideo) {
      // A recording has already started, do nothing.
      return;
    }
    try {
      _timer = Timer.periodic(const Duration(seconds: 1), (_) {
        _setupRecordTimeStr();
      });
      await controller!.startVideoRecording();
      setState(() {
        _isRecordingInProgress = true;
        print(_isRecordingInProgress);
      });
    } on CameraException catch (e) {
      print('Error starting to record video: $e');
    }
  }

  /// 停止视频录制过程
  Future<XFile?> stopVideoRecording() async {
    if (!controller!.value.isRecordingVideo) {
      // Recording is already is stopped state
      return null;
    }
    try {
      XFile file = await controller!.stopVideoRecording();
      _timer?.cancel();
      setState(() {
        _isRecordingInProgress = false;
        print(_isRecordingInProgress);
      });
      return file;
    } on CameraException catch (e) {
      print('Error stopping video recording: $e');
      return null;
    }
  }

  void _setupRecordTimeStr() {
    ++_startRecordDuration;
    if (_startRecordDuration >= widget.maxRecordDuration) {
      _endTakeVideo();
    }
    var duration = Duration(seconds: _startRecordDuration);

    var hour = duration.inHours;
    var minutes = duration.inMinutes - hour * 60;
    var seconds = duration.inSeconds - duration.inMinutes * 60;

    setState(() {
      _recordTimeStr = '${fixedIntString(hour, fixed: 2)}:${fixedIntString(minutes, fixed: 2)}:${fixedIntString(seconds, fixed: 2)}';
    });
  }

  String fixedIntString(
    int a, {
    required int fixed,
  }) {
    var str = a.toString();
    if (str.length < fixed) {
      return str.padLeft(fixed, '0');
    }
    return str;
  }
}
